/*
 * 上海远境文化传媒有限公司 版权所有
 */
package ext.func;

import ext.Func;
import models.enums.LicenseEdition;

import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 功能开关定义.
 *
 * 定义公司类型对应的可用功能.
 */
public class FuncDefine {

    private final static Map<LicenseEdition, Set<Func>> licenseFuncMap;

    static {
        licenseFuncMap = new ConcurrentHashMap<>();

        Builder basicBuilder = Builder.newInstance()
                .add(Func.REPORT);

        basicBuilder.putTo(licenseFuncMap, LicenseEdition.BASIC);

        // 试用版本
        Builder trialBuilder = Builder.from(basicBuilder);
        trialBuilder.putTo(licenseFuncMap, LicenseEdition.TRIAL);

        // 全功能开发测试
        Builder.newInstance()
                .addAll(Func.values())
                .putTo(licenseFuncMap, LicenseEdition.TESTING);
    }

    public static Set<Func> getFuncSet(LicenseEdition licenseEdition) {
        return licenseFuncMap.get(licenseEdition);
    }

    public static List<Func> getAllFuncList() {
        return Arrays.asList(Func.values());
    }

    private static class Builder {
        private Set<Func> funcSet;

        public static Builder newInstance() {
            Builder builder = new Builder();
            builder.funcSet = new HashSet<>();
            return builder;
        }

        public static Builder from(Builder otherBuilder) {
            Builder builder = new Builder();
            builder.funcSet = new HashSet<>();
            builder.funcSet.addAll(otherBuilder.funcSet);
            return builder;
        }

        public Builder add(Func func) {
            this.funcSet.add(func);
            return this;
        }

        public Builder remove(Func func) {
            this.funcSet.remove(func);
            return this;
        }


        public Builder addAll(Func[] funcs) {
            Collections.addAll(this.funcSet, funcs);
            return this;
        }

        public Builder addAll(Collection<Func> funcCollection) {
            this.funcSet.addAll(funcCollection);
            return this;
        }

        public void putTo(Map<LicenseEdition, Set<Func>> licenseFuncMap, LicenseEdition licenseEdition) {
            Set<Func> cloneFuncSet = new HashSet<>();
            cloneFuncSet.addAll(this.funcSet);
            licenseFuncMap.put(licenseEdition, cloneFuncSet);
        }

    }
}
